Public Class EditForm


    Private _tabSize As Integer

    Public ReadOnly Property Code() As String
        Get
            Return TextBoxCode.Text
        End Get
    End Property

    Public ReadOnly Property Language() As String
        Get
            Return DirectCast(ListLanguage.SelectedItem, PluginSetting.LanguageItem).ClassName
        End Get
    End Property

    Public Sub SetTabSize(ByVal value As Integer)
        Const EM_SETTABSTOPS As Integer = &HCB
        NativeMethods.SendMessage(TextBoxCode.Handle, EM_SETTABSTOPS, 1, New Integer() {value * 4})
        _tabSize = value
    End Sub

    Public Sub New(ByVal selectedLanguage As String, ByVal code As String)
        InitializeComponent()

        TextBoxCode.Text = code
        ListLanguage.Items.AddRange(PluginSetting.Languages.ToArray)
        Try
            ListLanguage.SelectedItem = (From l In PluginSetting.Languages Where selectedLanguage = l.ClassName).Single
        Catch ex As InvalidOperationException
            ListLanguage.SelectedIndex = 0
        End Try

        TextBoxCode.Font = My.Settings.EditorFont
        TextBoxCode.SelectionStart = 0
        TextBoxCode.SelectionLength = 0

        Me.Size = My.Settings.EditorSize
    End Sub

    Public Sub SelectAll()
        TextBoxCode.SelectionStart = 0
        TextBoxCode.SelectionLength = TextBoxCode.Text.Length
    End Sub

    Public Sub FixIndent()
        If _tabSize = 0 Then
            Exit Sub
        End If
        Dim lines = TextBoxCode.Text.Split(CChar(vbLf))

        Dim minCount = Integer.MaxValue
        For Each l In lines
            If l.Trim = "" Then
                Continue For
            End If

            Dim count = 0
            Dim offset = 0
            Dim spaces As Integer
            For i = 0 To l.Length - 1
                If l(i) = " " Then
                    count += 1
                ElseIf l(i) = vbTab Then
                    spaces = _tabSize - (i + offset) Mod _tabSize
                    count += spaces
                    offset += spaces - 1
                Else
                    Exit For
                End If
            Next
            If minCount > count Then
                minCount = count
            End If
            If minCount = 0 Then
                Exit Sub
            End If
        Next

        Dim code = New System.Text.StringBuilder
        For Each l In lines
            If l.Trim = "" Then
                code.Append(vbCrLf)
            Else
                ' Tab to Space
                Dim line = New System.Text.StringBuilder
                Dim spaces As Integer
                Dim offset = 0
                For i = 0 To l.Length - 1
                    If l(i) = " " Then
                        line.Append(" ")
                    ElseIf l(i) = vbTab Then
                        spaces = _tabSize - (i + offset) Mod _tabSize
                        line.Append(" "c, spaces)
                        offset += spaces - 1
                    Else
                        line.Append(l.Substring(i).TrimEnd)
                        Exit For
                    End If
                Next
                code.Append(line.ToString.Substring(minCount) & vbCrLf)
            End If
        Next
        TextBoxCode.Text = code.ToString.TrimEnd
        TextBoxCode.SelectionStart = 0
        TextBoxCode.SelectionLength = 0

    End Sub

    Private Sub ButtonOk_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonOk.Click
        Me.DialogResult = Windows.Forms.DialogResult.OK
        My.Settings.EditorSize = Me.Size
        My.Settings.Save()
    End Sub

    Private Sub ButtonFixIndent_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonFixIndent.Click
        FixIndent()
    End Sub

    Private Sub ButtonClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonClear.Click
        TextBoxCode.Clear()
    End Sub

    Private KeyHandled As Boolean
    Private Sub TextBoxCode_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBoxCode.KeyDown
        If e.KeyCode = Windows.Forms.Keys.A And e.Control Then
            TextBoxCode.SelectAll()
            KeyHandled = True
        Else
            KeyHandled = False
        End If
    End Sub

    Private Sub TextBoxCode_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBoxCode.KeyPress
        e.Handled = KeyHandled
    End Sub

End Class